Skip to content

Fix #26039: REPL prompt disappears when builtins/globals shadowed under PYTHONSTARTUP - #26045

Open
Mohit Yadav (mohityadav8) wants to merge 4 commits into
microsoft:mainfrom
mohityadav8:fix-pythonrc-prompt-shadowed-builtins
Open

Fix #26039: REPL prompt disappears when builtins/globals shadowed under PYTHONSTARTUP#26045
Mohit Yadav (mohityadav8) wants to merge 4 commits into
microsoft:mainfrom
mohityadav8:fix-pythonrc-prompt-shadowed-builtins

Conversation

@mohityadav8

@mohityadav8 Mohit Yadav (mohityadav8) commented Jul 19, 2026

Copy link
Copy Markdown

Fixes #26039

PYTHONSTARTUP executes pythonrc.py's code directly inside the user's __main__ namespace rather than importing it as a module. That means PS1.__str__.__globals__ is the user's namespace — so shadowing any name it relies on at prompt-render time (int, sys, str, bool, original_ps1, get_last_command) breaks str(sys.ps1) and silently kills the prompt.

This captures the real objects into private _-prefixed aliases right after they're defined, before any user code runs, so later reassignment of those names in __main__ can't affect the prompt anymore.

How I tested:

  • Reproduced by exec-ing pythonrc.py's source into a synthetic __main__ dict (mirroring the real PYTHONSTARTUP path) and shadowing int/sys/str/bool/original_ps1/get_last_command — confirmed it broke on the original file and is fixed on the patched one.
  • Added test_prompt_survives_shadowed_builtins_under_pythonstartup, which encodes that reproduction as a regression test. The existing tests import pythonrc as a normal module, which gives PS1 its own module namespace instead of __main__ — that's why they never caught this bug.
  • npm run check-python (ruff check, ruff format --check, pyright) — clean, 0 errors.
  • python -m pytest python_files/tests/test_shell_integration.py -v — 5/5 passed.

Notes for reviewers: the fix is intentionally minimal (capture at definition time) rather than moving the class into a separate module, since pythonStartup.ts only ever copies the single pythonrc.py file to the PYTHONSTARTUP location — splitting into two files would require extension-side deployment changes.

@mohityadav8

Copy link
Copy Markdown
Author

Eleanor Boyd (@eleanorjboyd) hey I think Icannot add label in this

@eleanorjboyd Eleanor Boyd (eleanorjboyd) added the bug Issue identified by VS Code Team member as probable bug label Jul 27, 2026
@mohityadav8

Copy link
Copy Markdown
Author

Eleanor Boyd (@eleanorjboyd) all cehcks are passed

@edvilme

Copy link
Copy Markdown

Hello Mohit Yadav (@mohityadav8)
Thanks for working on this! We recently merged #26148 which should avoid many of the namespace issues and relates to your PR. Please resolve the merge conflicts and we can take a look :)

@bschnurr

Bill Schnurr (bschnurr) commented Sep 11, 2026

Copy link
Copy Markdown
Member

🔒 Automated review in progress — Bill Schnurr (@bschnurr) is auto-reviewing this PR.

Comment thread python_files/pythonrc.py
# str will get called for every prompt with exit code to show success/failure
def __str__(self):
exit_code = int(bool(self.hooks.failure_flag))
exit_code = _int(_bool(self.hooks.failure_flag))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning · Non-blocking recommendation

The private aliases remain mutable entries in the user's __main__ namespace, so assigning _int, _sys, _str, _bool, or _original_ps1 can still break or alter prompt rendering. Capture these dependencies in closure cells or function defaults, and cover shadowing the private aliases too.

[verified]

Comment thread python_files/pythonrc.py
# __main__.__dict__. That means PS1.__str__.__globals__ IS the user's
# namespace: if the user later shadows a name we rely on at prompt-render
# time (e.g. `int = 20`, `sys = 1`, `original_ps1 = ...`), a plain global
# lookup would resolve to the user's value instead of ours and raise,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue · Please address or respond

Remove the issue reference from this production-code comment. docs/pylancewiki/review/issue-references.md prohibits issue links in production-code comments, with no applicable exception here.

[verified]

print.assert_any_call("Ctrl click to launch VS Code Native REPL")


def test_prompt_survives_shadowed_builtins_under_pythonstartup():

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue · Please address or respond

Remove the issue reference from this test docstring and keep the linkage in PR or commit metadata. Committed regression tests are explicitly covered by docs/pylancewiki/review/issue-references.md.

[verified]

@bschnurr Bill Schnurr (bschnurr) added the review-auto:changes-requested Automated review: posted blocking findings to address. label Sep 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Issue identified by VS Code Team member as probable bug review-auto:changes-requested Automated review: posted blocking findings to address.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Terminal REPL: >>> prompt disappears after assigning to int (pythonrc.py PS1 breaks when builtins are shadowed)

4 participants